Assignment 3: Accessing Operational Data¶
Let's look at some operational data down in the Caribbean Sea during this year's Hurricane season. This joint meteorological and oceanographical effort in the Caribbean was first started in 2021; previous MOO student Casey Jones focused on this early effort for his thesis. Now years later, let's evaluate this crucial real-time data.¶
In [1]:
# First we begin with some imports
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import datetime
import cmocean.cm as cmo
import cartopy.crs as ccrs
import cool_maps.plot as cplt
How can we look at this data? MARACOOS OceansMap and IOOS GliderMap are two great sources and data portals. Let's look at some glider data first!¶
In [56]:
sg663 = 'https://gliders.ioos.us/erddap/tabledap/SG663-20240710T1312.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg663 = pd.read_csv(sg663, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg663
Out[56]:
| time | latitude | longitude | depth | salinity | temperature | density | |
|---|---|---|---|---|---|---|---|
| 0 | 2024-07-10 13:16:13+00:00 | 18.337942 | -69.635303 | 0.441536 | NaN | 29.681566 | NaN |
| 1 | 2024-07-10 13:16:13+00:00 | 18.337942 | -69.635303 | 0.770287 | NaN | 29.681566 | NaN |
| 2 | 2024-07-10 13:16:13+00:00 | 18.337942 | -69.635303 | 0.783423 | NaN | 29.681408 | NaN |
| 3 | 2024-07-10 13:16:13+00:00 | 18.337942 | -69.635303 | 0.783299 | NaN | 29.676233 | NaN |
| 4 | 2024-07-10 13:16:13+00:00 | 18.337942 | -69.635303 | 0.960860 | NaN | 29.680200 | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 410771 | 2024-09-26 11:31:09+00:00 | 16.464665 | -68.407257 | 3.534607 | 35.701324 | 30.376059 | 1022.12274 |
| 410772 | 2024-09-26 11:31:09+00:00 | 16.464665 | -68.407257 | 2.402115 | 35.697620 | 30.381084 | 1022.11820 |
| 410773 | 2024-09-26 11:31:09+00:00 | 16.464665 | -68.407257 | 1.441740 | 35.701443 | 30.382212 | 1022.12067 |
| 410774 | 2024-09-26 11:31:09+00:00 | 16.464665 | -68.407257 | 0.295104 | NaN | 30.384502 | 1022.11780 |
| 410775 | 2024-09-26 11:31:09+00:00 | 16.464665 | -68.407257 | -0.001601 | NaN | 30.312267 | NaN |
410776 rows × 7 columns
Let's plot the data to see if we pulled the right glider. So let's visualize it on a cool_maps map, and have the colorbar indicate time.¶
In [7]:
# First we set the extent
extent = [-70.5, -62, 14.5, 24.5]
# Then create our cool_maps figure
fig,axs = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')
# Then plot our data onto the figure
ax_sg663 = plt.scatter(sg663['longitude'],sg663['latitude'],c=sg663['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool',
norm=plt.Normalize(vmin=sg663['time'].min().value,
vmax=sg663['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);
# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));
Look's good!¶
How about looking at some Saildrone data? If we check OceansMap, we can turn on this year's Hurricane Saildrone layer.¶
If we want to access the data, we can click the little i for more information, and follow the link to the ERDDAP page.¶
That takes us to the MARACOOS ERDDAP page that serves all the data the OceansMap visualizes. You'll often find the data on multiple ERDDAP pages, like this NOAA one from PMEL, which may serve it for longer than the MARACOOS one. For now, let's use the MARACOOS page. Since there aren't a lot of variables, let's leave them all checked and generate the URL. Since we're not being selective with the variables, we can remove everything after the .csv in the URL if we want a cleaner look.¶
In [65]:
sd1041 = 'https://erddap.maracoos.org/erddap/tabledap/sd1041_hurricane_2024.csv'
sd1041 = pd.read_csv(sd1041, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1041
Out[65]:
| latitude | longitude | time | trajectory | TEMP_AIR_MEAN | RH_MEAN | BARO_PRES_MEAN | TEMP_SBE37_MEAN | WIND_FROM_MEAN | WIND_SPEED_MEAN | SAL_SBE37_MEAN | WAVE_DOMINANT_PERIOD | WAVE_SIGNIFICANT_HEIGHT | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 18.233480 | -64.779853 | 2024-06-25 14:00:00+00:00 | 1041.0 | 29.63 | 80.79 | 1016.71 | 29.8179 | 98.2 | 9.07 | 36.3313 | 6.10 | 1.598 |
| 1 | 18.234176 | -64.779904 | 2024-06-25 14:01:00+00:00 | 1041.0 | 29.60 | 80.89 | 1016.70 | 29.8168 | 99.4 | 8.80 | 36.3313 | 6.10 | 1.593 |
| 2 | 18.234829 | -64.779923 | 2024-06-25 14:02:00+00:00 | 1041.0 | 29.61 | 81.66 | 1016.68 | 29.8158 | 100.6 | 8.76 | 36.3324 | 6.10 | 1.590 |
| 3 | 18.235451 | -64.780032 | 2024-06-25 14:03:00+00:00 | 1041.0 | 29.61 | 81.98 | 1016.68 | 29.8157 | 94.9 | 8.47 | 36.3309 | 6.10 | 1.593 |
| 4 | 18.236083 | -64.780102 | 2024-06-25 14:04:00+00:00 | 1041.0 | 29.61 | 81.59 | 1016.67 | 29.8156 | 93.6 | 8.71 | 36.3314 | 6.10 | 1.584 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 135115 | 18.878843 | -67.258573 | 2024-09-26 21:55:00+00:00 | 1041.0 | 30.32 | 78.27 | 1012.04 | 30.6961 | 90.8 | 7.44 | 35.9019 | 10.67 | 1.409 |
| 135116 | 18.879126 | -67.258541 | 2024-09-26 21:56:00+00:00 | 1041.0 | NaN | NaN | NaN | NaN | 81.1 | 7.47 | NaN | 10.67 | 1.418 |
| 135117 | 18.879459 | -67.258541 | 2024-09-26 21:57:00+00:00 | 1041.0 | NaN | NaN | NaN | NaN | 79.0 | 7.42 | NaN | 10.67 | 1.432 |
| 135118 | 18.879757 | -67.258579 | 2024-09-26 21:58:00+00:00 | 1041.0 | NaN | NaN | NaN | NaN | 80.9 | 7.68 | NaN | 10.67 | 1.443 |
| 135119 | 18.880131 | -67.258579 | 2024-09-26 21:59:00+00:00 | 1041.0 | NaN | NaN | NaN | NaN | 86.8 | 6.78 | NaN | 10.67 | 1.456 |
135120 rows × 13 columns
Now let's repeat the same mapping process we did above, but for the saildrone this time.¶
In [113]:
# First we set the extent
extent = [-70.5, -62, 14.5, 24.5]
# Then create our cool_maps figure
fig,axs = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')
# Then plot our data onto the figure
ax_sd1041 = plt.scatter(sd1041['longitude'],sd1041['latitude'],c=sd1041['time'], marker="o", edgecolors='none',cmap='cool', alpha = .2, transform=ccrs.PlateCarree())
# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool',
norm=plt.Normalize(vmin=sd1041['time'].min().value,
vmax=sd1041['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);
# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));
1. Using the following URLs for the other saildrones & gliders, load in all of the datasets as done above.¶
In [80]:
sg649 = 'https://gliders.ioos.us/erddap/tabledap/SG649-20240712T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg649 = pd.read_csv(sg649, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg649
Out[80]:
| time | latitude | longitude | depth | salinity | temperature | density | |
|---|---|---|---|---|---|---|---|
| 0 | 2024-07-12 11:37:53+00:00 | 18.463570 | -67.304019 | 0.617856 | NaN | 29.697739 | NaN |
| 1 | 2024-07-12 11:37:53+00:00 | 18.463570 | -67.304019 | 0.800471 | NaN | 29.699413 | NaN |
| 2 | 2024-07-12 11:37:53+00:00 | 18.463570 | -67.304019 | 0.771923 | NaN | 29.701405 | NaN |
| 3 | 2024-07-12 11:37:53+00:00 | 18.463570 | -67.304019 | 0.911291 | NaN | 29.703192 | NaN |
| 4 | 2024-07-12 11:37:53+00:00 | 18.463570 | -67.304019 | 0.933263 | NaN | 29.703768 | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 404217 | 2024-09-26 22:17:33+00:00 | 18.960283 | -65.823707 | 3.343639 | 35.458070 | 30.480658 | 1021.9043 |
| 404218 | 2024-09-26 22:17:33+00:00 | 18.960283 | -65.823707 | 1.995474 | 35.456306 | 30.482527 | 1021.9023 |
| 404219 | 2024-09-26 22:17:33+00:00 | 18.960283 | -65.823707 | 0.838080 | NaN | 30.477050 | 1021.9044 |
| 404220 | 2024-09-26 22:17:33+00:00 | 18.960283 | -65.823707 | -0.067845 | NaN | 30.463682 | NaN |
| 404221 | 2024-09-26 22:17:33+00:00 | 18.960283 | -65.823707 | -0.230565 | NaN | 30.388618 | NaN |
404222 rows × 7 columns
In [57]:
# Saildrones from http://erddap.maracoos.org/erddap/search/index.html?page=1&itemsPerPage=1000&searchFor=Saildrone%20Atlantic%202024
sd1031 = 'http://erddap.maracoos.org/erddap/tabledap/sd1031_hurricane_2024.csv'
sd1031 = pd.read_csv(sd1031, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1041 = 'http://erddap.maracoos.org/erddap/tabledap/sd1041_hurricane_2024.csv'
sd1041 = pd.read_csv(sd1041, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1036 = 'http://erddap.maracoos.org/erddap/tabledap/sd1036_hurricane_2024.csv'
sd1036 = pd.read_csv(sd1036, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1040 = 'http://erddap.maracoos.org/erddap/tabledap/sd1040_hurricane_2024.csv'
sd1040 = pd.read_csv(sd1040, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1057 = 'http://erddap.maracoos.org/erddap/tabledap/sd1057_hurricane_2024.csv'
sd1057 = pd.read_csv(sd1057, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1068 = 'http://erddap.maracoos.org/erddap/tabledap/sd1068_hurricane_2024.csv'
sd1068 = pd.read_csv(sd1068, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1069 = 'http://erddap.maracoos.org/erddap/tabledap/sd1069_hurricane_2024.csv'
sd1069 = pd.read_csv(sd1069, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1083 = 'http://erddap.maracoos.org/erddap/tabledap/sd1083_hurricane_2024.csv'
sd1083 = pd.read_csv(sd1083, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sd1091 = 'http://erddap.maracoos.org/erddap/tabledap/sd1091_hurricane_2024.csv'
sd1091 = pd.read_csv(sd1091, sep=',', skiprows=range(1,2), parse_dates = ['time'])
# Gliders from https://gliders.ioos.us/erddap/tabledap/index.html?page=1&itemsPerPage=1000
ng278 = 'https://gliders.ioos.us/erddap/tabledap/ng278-20240711T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng278 = pd.read_csv(ng278, sep=',', skiprows=range(1,2), parse_dates = ['time'])
ng656 = 'https://gliders.ioos.us/erddap/tabledap/ng656-20240613T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng656 = pd.read_csv(ng656, sep=',', skiprows=range(1,2), parse_dates = ['time'])
ng783 = 'https://gliders.ioos.us/erddap/tabledap/ng783-20240807T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng783 = pd.read_csv(ng783, sep=',', skiprows=range(1,2), parse_dates = ['time'])
ng738 = 'https://gliders.ioos.us/erddap/tabledap/ng738-20240807T0000.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
ng738 = pd.read_csv(ng738, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg663 = 'https://gliders.ioos.us/erddap/tabledap/SG663-20240710T1312.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg663 = pd.read_csv(sg663, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg678 = 'https://gliders.ioos.us/erddap/tabledap/SG678-20240617T1202.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg678 = pd.read_csv(sg678, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg630 = 'https://gliders.ioos.us/erddap/tabledap/SG630-20240713T1103.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg630 = pd.read_csv(sg630, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg610 = 'https://gliders.ioos.us/erddap/tabledap/SG610-20240711T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg610 = pd.read_csv(sg610, sep=',', skiprows=range(1,2), parse_dates = ['time'])
sg649 = 'https://gliders.ioos.us/erddap/tabledap/SG649-20240712T1133.csv?time%2Clatitude%2Clongitude%2Cdepth%2Csalinity%2Ctemperature%2Cdensity'
sg649 = pd.read_csv(sg649, sep=',', skiprows=range(1,2), parse_dates = ['time'])
2A. Create a single, large map like above including all the 9 saildrone and 9 glider tracks, with each colored by time.¶
In [83]:
# First we set the extent
extent = [-85, -50, 14.5, 34]
# Then create our cool_maps figure
fig,axs = cplt.create(extent, proj=ccrs.Mercator(), bathymetry=True, isobaths=(-1000, -10), figsize=(10,6), oceancolor='w')
# Then plot our data onto the figure
ax_ng278 = plt.scatter(ng278['longitude'],ng278['latitude'],c=ng278['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng656 = plt.scatter(ng656['longitude'],ng656['latitude'],c=ng656['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng783 = plt.scatter(ng783['longitude'],ng783['latitude'],c=ng783['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_ng738 = plt.scatter(ng738['longitude'],ng738['latitude'],c=ng738['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg663 = plt.scatter(sg663['longitude'],sg663['latitude'],c=sg663['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg678 = plt.scatter(sg678['longitude'],sg678['latitude'],c=sg678['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg630 = plt.scatter(sg630['longitude'],sg630['latitude'],c=sg630['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg610 = plt.scatter(sg610['longitude'],sg610['latitude'],c=sg610['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sg649 = plt.scatter(sg649['longitude'],sg649['latitude'],c=sg649['time'], marker="o", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1031 = plt.scatter(sd1031['longitude'],sd1031['latitude'],c=sd1031['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1041 = plt.scatter(sd1041['longitude'],sd1041['latitude'],c=sd1041['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1036 = plt.scatter(sd1036['longitude'],sd1036['latitude'],c=sd1036['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1040 = plt.scatter(sd1040['longitude'],sd1040['latitude'],c=sd1040['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1057 = plt.scatter(sd1057['longitude'],sd1057['latitude'],c=sd1057['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1068 = plt.scatter(sd1068['longitude'],sd1068['latitude'],c=sd1068['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1069 = plt.scatter(sd1069['longitude'],sd1069['latitude'],c=sd1069['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1083 = plt.scatter(sd1083['longitude'],sd1083['latitude'],c=sd1083['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
ax_sd1091 = plt.scatter(sd1091['longitude'],sd1091['latitude'],c=sd1091['time'], marker="x", edgecolors='none',cmap='cool', alpha = .5, transform=ccrs.PlateCarree())
# Date colorbar code taken from: https://stackoverflow.com/questions/51160705/plot-time-series-with-colorbar-in-pandas-matplotlib
# Define your mappable for colorbar creation
sm = plt.cm.ScalarMappable(cmap='cool',
norm=plt.Normalize(vmin=ng278['time'].min().value,
vmax=sg649['time'].max().value));
# Add the colorbar
sm._A = [];
cbar = plt.colorbar(sm, ax = axs);
# Change the numeric ticks into ones that match. Time format options detailed here: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
cbar.ax.set_yticklabels(pd.to_datetime(cbar.get_ticks()).strftime(date_format='%b %d'));
fig.text(0.5, 0.01, "Figure 1: Map compiling all glider and saildron missions in specific location. Saildrones are marked with an (x) where gliders are marked with (o)", ha='center')
Out[83]:
Text(0.5, 0.01, 'Figure 1: Map compiling all glider and saildron missions in specific location. Saildrones are marked with an (x) where gliders are marked with (o)')
2B. Caption the figure, describing the key takeaways.¶
see above¶
3A. Plot a figure with 9 x 2 subplots, showing temperature for each of the 18 platforms. Use xlim to align the subplots in time. The 9 saildrone plots should be air temperature by time, with the markers colored by water temperature. The 9 glider plots should be depth by time, with the markers colored by water temperature. Be sure to add a colorbar and labels when appropriate.¶
In [110]:
import matplotlib.dates as mdates
In [112]:
fig, axs = plt.subplots(9, 2, figsize=(7, 20))
xlim_start = pd.to_datetime('2024-05-25')
xlim_end = pd.to_datetime('2024-09-30')
# Saildrone plots (air temp vs. time, colored by water temp)
sc1 = axs[0, 0].scatter(sd1031['time'], sd1031['TEMP_AIR_MEAN'], c=sd1031['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc1, ax=axs[0, 0])
axs[0, 0].set_title('Saildrone 1031')
axs[0, 0].set_xlabel('Time')
axs[0, 0].set_ylabel('Air Temperature[°C]')
axs[0, 0].set_xlim([xlim_start, xlim_end])
axs[0, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[0, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc2 = axs[1, 0].scatter(sd1041['time'], sd1041['TEMP_AIR_MEAN'], c=sd1041['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc2, ax=axs[1, 0])
axs[1, 0].set_title('Saildrone 1041')
axs[1, 0].set_xlabel('Time')
axs[1, 0].set_ylabel('Air Temperature[°C]')
axs[1, 0].set_xlim([xlim_start, xlim_end])
axs[1, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[1, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc3 = axs[2, 0].scatter(sd1036['time'], sd1036['TEMP_AIR_MEAN'], c=sd1036['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc3, ax=axs[2, 0])
axs[2, 0].set_title('Saildrone 1036')
axs[2, 0].set_xlabel('Time')
axs[2, 0].set_ylabel('Air Temperature[°C]')
axs[2, 0].set_xlim([xlim_start, xlim_end])
axs[2, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[2, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc4 = axs[3, 0].scatter(sd1040['time'], sd1040['TEMP_AIR_MEAN'], c=sd1040['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc4, ax=axs[3, 0])
axs[3, 0].set_title('Saildrone 1040')
axs[3, 0].set_xlabel('Time')
axs[3, 0].set_ylabel('Air Temperature[°C]')
axs[3, 0].set_xlim([xlim_start, xlim_end])
axs[3, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[3, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc5 = axs[4, 0].scatter(sd1057['time'], sd1057['TEMP_AIR_MEAN'], c=sd1057['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc5, ax=axs[4, 0])
axs[4, 0].set_title('Saildrone 1057')
axs[4, 0].set_xlabel('Time')
axs[4, 0].set_ylabel('Air Temperature[°C]')
axs[4, 0].set_xlim([xlim_start, xlim_end])
axs[4, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[4, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc6 = axs[5, 0].scatter(sd1068['time'], sd1068['TEMP_AIR_MEAN'], c=sd1068['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc6, ax=axs[5, 0])
axs[5, 0].set_title('Saildrone 1068')
axs[5, 0].set_xlabel('Time')
axs[5, 0].set_ylabel('Air Temperature[°C]')
axs[5, 0].set_xlim([xlim_start, xlim_end])
axs[5, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[5, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc7 = axs[6, 0].scatter(sd1069['time'], sd1069['TEMP_AIR_MEAN'], c=sd1069['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc7, ax=axs[6, 0])
axs[6, 0].set_title('Saildrone 1069')
axs[6, 0].set_xlabel('Time')
axs[6, 0].set_ylabel('Air Temperature[°C]')
axs[6, 0].set_xlim([xlim_start, xlim_end])
axs[6, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[6, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc8 = axs[7, 0].scatter(sd1083['time'], sd1083['TEMP_AIR_MEAN'], c=sd1083['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc8, ax=axs[7, 0])
axs[7, 0].set_title('Saildrone 1083')
axs[7, 0].set_xlabel('Time')
axs[7, 0].set_ylabel('Air Temperature[°C]')
axs[7, 0].set_xlim([xlim_start, xlim_end])
axs[7, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[7, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc9 = axs[8, 0].scatter(sd1091['time'], sd1091['TEMP_AIR_MEAN'], c=sd1091['TEMP_SBE37_MEAN'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc9, ax=axs[8, 0])
axs[8, 0].set_title('Saildrone 1091')
axs[8, 0].set_xlabel('Time')
axs[8, 0].set_ylabel('Air Temperature[°C]')
axs[8, 0].set_xlim([xlim_start, xlim_end])
axs[8, 0].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[8, 0].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
# Glider plots (depth vs. time, colored by water temperature)
sc10 = axs[0, 1].scatter(ng278['time'], ng278['depth'], c=ng278['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc10, ax=axs[0, 1])
axs[0, 1].invert_yaxis()
axs[0, 1].set_title('Glider 278')
axs[0, 1].set_xlabel('Time')
axs[0, 1].set_ylabel('Depth[m]')
axs[0, 1].set_xlim([xlim_start, xlim_end])
axs[0, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[0, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc11 = axs[1, 1].scatter(ng656['time'], ng656['depth'], c=ng656['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc11, ax=axs[1, 1])
axs[1, 1].invert_yaxis()
axs[1, 1].set_title('Glider 656')
axs[1, 1].set_xlabel('Time')
axs[1, 1].set_ylabel('Depth[m]')
axs[1, 1].set_xlim([xlim_start, xlim_end])
axs[1, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[1, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc12 = axs[2, 1].scatter(ng783['time'], ng783['depth'], c=ng783['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc12, ax=axs[2, 1])
axs[2, 1].invert_yaxis()
axs[2, 1].set_title('Glider 783')
axs[2, 1].set_xlabel('Time')
axs[2, 1].set_ylabel('Depth[m]')
axs[2, 1].set_xlim([xlim_start, xlim_end])
axs[2, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[2, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc13 = axs[3, 1].scatter(ng738['time'], ng738['depth'], c=ng738['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc13, ax=axs[3, 1])
axs[3, 1].invert_yaxis()
axs[3, 1].set_title('Glider 738')
axs[3, 1].set_xlabel('Time')
axs[3, 1].set_ylabel('Depth[m]')
axs[3, 1].set_xlim([xlim_start, xlim_end])
axs[3, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[3, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc14 = axs[4, 1].scatter(sg663['time'], sg663['depth'], c=sg663['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc14, ax=axs[4, 1])
axs[4, 1].invert_yaxis()
axs[4, 1].set_title('Glider 663')
axs[4, 1].set_xlabel('Time')
axs[4, 1].set_ylabel('Depth[m]')
axs[4, 1].set_xlim([xlim_start, xlim_end])
axs[4, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[4, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc15 = axs[5, 1].scatter(sg678['time'], sg678['depth'], c=sg678['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc15, ax=axs[5, 1])
axs[5, 1].invert_yaxis()
axs[5, 1].set_title('Glider 678')
axs[5, 1].set_xlabel('Time')
axs[5, 1].set_ylabel('Depth[m]')
axs[5, 1].set_xlim([xlim_start, xlim_end])
axs[5, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[5, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc16 = axs[6, 1].scatter(sg630['time'], sg630['depth'], c=sg630['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc16, ax=axs[6, 1])
axs[6, 1].invert_yaxis()
axs[6, 1].set_title('Glider 630')
axs[6, 1].set_xlabel('Time')
axs[6, 1].set_ylabel('Depth[m]')
axs[6, 1].set_xlim([xlim_start, xlim_end])
axs[6, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[6, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc17 = axs[7, 1].scatter(sg610['time'], sg610['depth'], c=sg610['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc17, ax=axs[7, 1])
axs[7, 1].invert_yaxis()
axs[7, 1].set_title('Glider 610')
axs[7, 1].set_xlabel('Time')
axs[7, 1].set_ylabel('Depth[m]')
axs[7, 1].set_xlim([xlim_start, xlim_end])
axs[7, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[7, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
sc18 = axs[8, 1].scatter(sg649['time'], sg649['depth'], c=sg649['temperature'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc18, ax=axs[8, 1])
axs[8, 1].invert_yaxis()
axs[8, 1].set_title('Glider 649')
axs[8, 1].set_xlabel('Time')
axs[8, 1].set_ylabel('Depth[m]')
axs[8, 1].set_xlim([xlim_start, xlim_end])
axs[8, 1].set_xticks(pd.date_range(xlim_start, xlim_end, freq='10D'))
axs[8, 1].set_xticklabels(pd.date_range(xlim_start, xlim_end, freq='10D').strftime('%m-%d'))
for ax in axs.flat:
plt.setp(ax.get_xticklabels(), rotation=45, ha='right')
#x_limits = [pd.Timestamp("2024-05-20"),pd.Timestamp("2024-09-30")]
#for ax in axs.flat:
#ax.set_xlim(x_limits)
fig.text(0.5, 0.001, "Figure 2: Left plots map out air temp vs time compared to sea surface temp of saildrones. Right side shows depth vs time compared to sea temp", ha='center')
plt.tight_layout()
plt.show()
#
In [114]:
#Highlights the difference in air temp to water temp for saildrones and shows temperature over depth for gliders. Allows for higher acuracy surface temps and detailed sea temps at depth for water columns.
4A. Plot the wind speed by the pressure, colored by wave height, for the saildrone plots as separate subplots.¶
In [101]:
fig, axs = plt.subplots(9, 1, figsize=(7, 20))
# Saildrone plots (air temp vs. time, colored by water temp)
sc1 = axs[0,].scatter(sd1031['BARO_PRES_MEAN'], sd1031['WIND_SPEED_MEAN'], c=sd1031['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc1, ax=axs[0,])
axs[0, ].set_title('Saildrone 1031')
axs[0, ].set_xlabel('Pressure')
axs[0, ].set_ylabel('Wind Speed')
sc2 = axs[1, ].scatter(sd1041['BARO_PRES_MEAN'], sd1041['WIND_SPEED_MEAN'], c=sd1041['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc2, ax=axs[1,])
axs[1, ].set_title('Saildrone 1041')
axs[1, ].set_xlabel('Pressure')
axs[1, ].set_ylabel('Wind Speed')
sc3 = axs[2, ].scatter(sd1036['BARO_PRES_MEAN'], sd1036['WIND_SPEED_MEAN'], c=sd1036['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc3, ax=axs[2, ])
axs[2, ].set_title('Saildrone 1036')
axs[2, ].set_xlabel('Pressure')
axs[2, ].set_ylabel('Wind Speed')
sc4 = axs[3, ].scatter(sd1040['BARO_PRES_MEAN'], sd1040['WIND_SPEED_MEAN'], c=sd1040['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc4, ax=axs[3, ])
axs[3, ].set_title('Saildrone 1040')
axs[3, ].set_xlabel('Pressure')
axs[3, ].set_ylabel('Wind Speed')
sc5 = axs[4, ].scatter(sd1057['BARO_PRES_MEAN'], sd1057['WIND_SPEED_MEAN'], c=sd1057['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc5, ax=axs[4, ])
axs[4, ].set_title('Saildrone 1057')
axs[4, ].set_xlabel('Pressure')
axs[4, ].set_ylabel('Wind Speed')
sc6 = axs[5, ].scatter(sd1068['BARO_PRES_MEAN'], sd1068['WIND_SPEED_MEAN'], c=sd1068['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc6, ax=axs[5,])
axs[5, ].set_title('Saildrone 1068')
axs[5, ].set_xlabel('Pressure')
axs[5, ].set_ylabel('Wind Speed')
sc7 = axs[6, ].scatter(sd1069['BARO_PRES_MEAN'], sd1069['WIND_SPEED_MEAN'], c=sd1069['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc7, ax=axs[6, ])
axs[6, ].set_title('Saildrone 1069')
axs[6, ].set_xlabel('Pressure')
axs[6, ].set_ylabel('Wind Speed')
sc8 = axs[7, ].scatter(sd1083['BARO_PRES_MEAN'], sd1083['WIND_SPEED_MEAN'], c=sd1083['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc8, ax=axs[7, ])
axs[7, ].set_title('Saildrone 1083')
axs[7, ].set_xlabel('Pressure')
axs[7, ].set_ylabel('Wind Speed')
sc9 = axs[8, ].scatter(sd1091['BARO_PRES_MEAN'], sd1091['WIND_SPEED_MEAN'], c=sd1091['WAVE_SIGNIFICANT_HEIGHT'], marker="x", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc9, ax=axs[8, ])
axs[8, ].set_title('Saildrone 1091')
axs[8, ].set_xlabel('Pressure')
axs[8, ].set_ylabel('Wind Speed')
x_limits = [950,1030]
for ax in axs.flat:
ax.set_xlim(x_limits)
fig.text(0.5, 0.001, "Figure 3: wind speed vs pressure compared to wave hights for saildrones", ha='center')
plt.tight_layout()
plt.show()
4B. Caption the figure, describing the key takeaways.¶
Higher wind speed leads to increased wave heights. Increased pressure leads to slower wind and shorter waves.¶
5A. Plot TS diagrams, colored by density, for the 9 gliders as separate subplots.¶
In [106]:
fig, axs = plt.subplots(9, 1, figsize=(7, 20))
sc10 = axs[0, ].scatter(ng278['salinity'], ng278['temperature'], c=ng278['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc10, ax=axs[0, ])
axs[0,].set_title('Glider 278')
axs[0,].set_xlabel('Salinity [PSU]')
axs[0,].set_ylabel('Temperature [°C]')
sc11 = axs[1,].scatter(ng656['salinity'], ng656['temperature'], c=ng656['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc11, ax=axs[1, ])
axs[1, ].set_title('Glider 656')
axs[1, ].set_xlabel('Salinity [PSU]')
axs[1, ].set_ylabel('Temperature [°C]')
sc12 = axs[2, ].scatter(ng783['salinity'], ng783['temperature'], c=ng783['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc12, ax=axs[2, ])
axs[2, ].set_title('Glider 783')
axs[2, ].set_xlabel('Salinity [PSU]')
axs[2, ].set_ylabel('Temperature [°C]')
sc13 = axs[3, ].scatter(ng738['salinity'], ng738['temperature'], c=ng738['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc13, ax=axs[3, ])
axs[3, ].set_title('Glider 738')
axs[3, ].set_xlabel('Salinity [PSU]')
axs[3, ].set_ylabel('Temperature [°C]')
sc14 = axs[4, ].scatter(sg663['salinity'], sg663['temperature'], c=sg663['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc14, ax=axs[4, ])
axs[4, ].set_title('Glider 663')
axs[4, ].set_xlabel('Salinity [PSU]')
axs[4, ].set_ylabel('Temperature [°C]')
sc15 = axs[5, ].scatter(sg678['salinity'], sg678['temperature'], c=sg678['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc15, ax=axs[5, ])
axs[5, ].set_title('Glider 678')
axs[5, ].set_xlabel('Salinity [PSU]')
axs[5, ].set_ylabel('Temperature [°C]')
sc16 = axs[6, ].scatter(sg630['salinity'], sg630['temperature'], c=sg630['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc16, ax=axs[6, ])
axs[6, ].set_title('Glider 630')
axs[6, ].set_xlabel('Salinity [PSU]')
axs[6, ].set_ylabel('Temperature [°C]')
sc17 = axs[7, ].scatter(sg610['salinity'], sg610['temperature'], c=sg610['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc17, ax=axs[7, ])
axs[7, ].set_title('Glider 610')
axs[7, ].set_xlabel('Salinity [PSU]')
axs[7, ].set_ylabel('Temperature [°C]')
sc18 = axs[8, ].scatter(sg649['salinity'], sg649['temperature'], c=sg649['density'], marker="o", edgecolors='none', cmap='cool', alpha=0.5)
plt.colorbar(sc18, ax=axs[8, ])
axs[8, ].set_title('Glider 649')
axs[8, ].set_xlabel('Salinity [PSU]')
axs[8, ].set_ylabel('Temperature [°C]')
x_limits = [33.3,38.5]
for ax in axs.flat:
ax.set_xlim(x_limits)
fig.text(0.5, 0.001, "Figure 4: Temp vs salinity compared to density for gliders", ha='center')
plt.tight_layout()
plt.show()
5B. Caption the figure, describing the key takeaways.¶
Higher temp of water linked to lower density levels. Salinity peak around mid point of tempurature range. Highest density at coolest tempurature and roughly 35 psu salinity.¶
6. What overall insights and conclusions can you synthesize from evaluating the data from these saildrones and gliders?¶
It is interesting to see how the plots are formed from two differnt systems. While some of the data is from different locations you can see similarities in tempurature readings. Each system collects different samples which is used to produce more detailed images of bodies of water. The range of data that can be collected is also increased.¶
In [ ]: